package de.fhffm.gaertnerei.gui;
/**
 * @author Kerim Septa & Julian Schmücker
 */

import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import de.fhffm.gaertnerei.exceptions.EingabeException;
import de.fhffm.gaertnerei.tabellen.Art;
import de.fhffm.gaertnerei.tabellen.Farbe;
import de.fhffm.gaertnerei.tabellen.Herkunft;
import de.fhffm.gaertnerei.tabellen.Pflanze;
import de.fhffm.gaertnerei.tabellen.Schaerfegrad;

@SuppressWarnings("serial")
public class NeuePflanzeFenster extends JFrame implements ActionListener {
	
	private JButton buttonOk = new JButton("OK");
	private JButton buttonAbbrechen = new JButton("Abbrechen");
	
	private JLabel labelSorte = new JLabel("Sorte");
	private JLabel labelArt = new JLabel("Art");
	private JLabel labelHerkunft = new JLabel("Herkunft");
	private JLabel labelFarbe = new JLabel("Farbe");
	private JLabel labelReifezeit = new JLabel("Reifezeit");
	private JLabel labelSchaerfegrad = new JLabel("Schaerfegrad");
	private JLabel labelErtrag = new JLabel("Ertrag");
	private JLabel labelTage = new JLabel ("Tage");
	private JLabel labelGramm = new JLabel ("gramm");
	private JLabel labelUeberschrift = new JLabel ("Neue Chilipflanze");
	
	private JTextField textfeldSorte = new JTextField(8);
	private JTextField textfeldHerkunft = new JTextField(8);
	private JTextField textfeldFarbe = new JTextField(8);
	private JTextField textfeldReifezeit = new JTextField(8);
	private JTextField textfeldErtrag = new JTextField(8);

	private JPanel panelEingabe = new JPanel(new GridLayout(7,2));
	private JPanel panelButton = new JPanel();
	private JPanel panelUeberschrift = new JPanel();
	
	private String[] arten = { "C.annum","C.baccatum","C.chinese","C.frutescens","C.pubescens"};
	private String[] schaerfe = {"0","1","2","3","4","5","6","7","8","9","10"};
	private String artString = null;
	private String farbeString = null;
	private String herkunftString = null;
	private String sorteString = null;
	private String ertragString = null;

	private int schaerfegradInt = 0;
	private int reifezeitInt = 0;
	private int ertragInt = 0;
	
	StringBuilder stringBuilder = new StringBuilder();
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private JComboBox artListe = new JComboBox(arten);
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private JComboBox schaerfeListe = new JComboBox(schaerfe);
	
	public NeuePflanzeFenster(){
		
		setzeToolTips();
		bestandteileAnordnen();
		ereignissensorenAnmeldung();
		erstelleFenster();
		
	}
	
	private void setzeToolTips() {
		
		textfeldHerkunft.setToolTipText("Das Land aus der die Pflanze kommt");
		textfeldReifezeit.setToolTipText("Eine für die Sorte übliche Reifezeit in Tagen");
		textfeldErtrag.setToolTipText("Ein für die Sorte üblicher Ertrag in gramm");	
		schaerfeListe.setToolTipText("<html> 0 = süße Chilis(ohne schärfe) <br> 1 = 0 - 1000 Scoville <br> 2 = 1.000 - 1.500 Scoville <br> 3 = 1.500 - 2.500 Scoville " +
		"<br> 4 = 2.500 - 5.000 Scoville <br> 5 = 5.000 - 15.000 Scoville <br> 6 = 15.000 - 30.000 Scoville <br> 7 = 30.000 - 50.000 Scoville <br>" +
		" 8 = 50.000 - 1000.000 Scoville <br> 9 = 100.000 - 350.000 Scoville <br> 10 = 350.000 - und höher </html>");
	}

	private void erstelleFenster() {
		
		setTitle("Neue Pflanze");	
		setSize(400,500);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);	
		pack();
		setVisible(true);
		setResizable(false);	
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		
		Object obj = e.getSource();

		if (obj == buttonAbbrechen) {	
			dispose();
		}
		
		/*
		 * Nachdem der Button Ok gedrückt wurde wird erstmal überprüft
		 * ob die Eingaben korrekt sind!
		 * Danach wird überprüft ob die zu speichernde Pflanze nicht schon vorhanden ist
		 * ist dies nicht der fall werden alle Attribute die aus einer anderen tabelle
		 * kommen überprüft, das heißt geguckt ob diese schon vorhanden sind oder nicht.
		 * Falls ein Wert schon vorhanden ist passiert nichts. 
		 * Falls nicht muss dieser erst in die etsprechende Tabelle eingefügt werden
		 * (fueger...ein();)
		 * Dies geschieht für jedes Attribut einzeln um probleme beim einfügen in die Datenbank 
		 * vorzubeugen.
		 * 
		 * Am ende werden der Pflanze alle Attribute zugewiesen und diese wird gespeichert
		 */
		
		if(obj == buttonOk){
	
			if(ueberpruefeEingabe()){
				
				if(pflanzeNichtVorhanden()){ 
					pruefeSchaerfegrad();
					pruefeFarbe();
					pruefeHerkunft();
					pruefeArt();
					fuegePflanzeEin();
					einfügenEnde();
					
				}else{
					System.out.println("Pflanze schon vorhanden!");
				}
			
			} else{
				
				System.out.println("Eingabe Fehler");
			}
		}
	}
	

	public void ereignissensorenAnmeldung(){
		
		buttonOk.addActionListener(this);
		buttonAbbrechen.addActionListener(this);
	}
	
	public void bestandteileAnordnen(){
		
		GroupLayout neuePflanzeFensterLayout = new GroupLayout(getContentPane());
		getContentPane().setLayout(neuePflanzeFensterLayout);
		
		neuePflanzeFensterLayout.setAutoCreateGaps(true);
		neuePflanzeFensterLayout.setAutoCreateContainerGaps(true);
		
		neuePflanzeFensterLayout.setVerticalGroup(neuePflanzeFensterLayout.createSequentialGroup().
				addComponent(panelUeberschrift).
				addComponent(panelEingabe).
				addComponent(panelButton)
		);

		neuePflanzeFensterLayout.setHorizontalGroup(neuePflanzeFensterLayout.createParallelGroup().
				addComponent(panelUeberschrift).
				addComponent(panelEingabe).
				addComponent(panelButton)
		);		
		
		panelUeberschriftAnordnen();
		panelEingabeAnordnen();
		panelButtonAnordnen();
	}
	
	private void panelUeberschriftAnordnen(){
		panelUeberschrift.setLayout(new FlowLayout());
		panelUeberschrift.add(labelUeberschrift);
		labelUeberschrift.setFont(new Font("Times new Roman", Font.BOLD, 22));
	}
	
	public void panelEingabeAnordnen(){
		
		GroupLayout eingabePanelLayout = new GroupLayout(panelEingabe);
		panelEingabe.setLayout(eingabePanelLayout);
		
		eingabePanelLayout.setAutoCreateGaps(true);
		eingabePanelLayout.setAutoCreateContainerGaps(true);
		
		eingabePanelLayout.setVerticalGroup(eingabePanelLayout.createSequentialGroup( ).
					addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
						addComponent( labelSorte ).
						addComponent( textfeldSorte )
					).
					addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
					  	addComponent( labelArt ).
						addComponent( artListe )
					).
					addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
						  	addComponent( labelHerkunft ).
							addComponent( textfeldHerkunft )
					).
			  		addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
			  			addComponent( labelFarbe ).
			  			addComponent( textfeldFarbe )
					).
			  		addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
						addComponent( labelSchaerfegrad ).
					  	addComponent( schaerfeListe )
					).
					addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
						addComponent( labelErtrag ).
						addComponent( textfeldErtrag ).
						addComponent( labelGramm )
					).
					addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
						addComponent( labelReifezeit ).
						addComponent( textfeldReifezeit ).
						addComponent( labelTage )));
						
		eingabePanelLayout.setHorizontalGroup(eingabePanelLayout.createParallelGroup( ).addGroup(eingabePanelLayout.createSequentialGroup( ).
					addGroup( eingabePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false ).
						addComponent( labelSorte, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( labelArt,GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( labelHerkunft,GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( labelFarbe, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( labelSchaerfegrad,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE ).
						addComponent( labelErtrag,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE ).
						addComponent( labelReifezeit,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE )
					).
					addGroup( eingabePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false ).
						addComponent( textfeldSorte, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( artListe,GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( textfeldHerkunft,GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( textfeldFarbe, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( schaerfeListe,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE ).
						addComponent( textfeldErtrag,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE ).
						addComponent( textfeldReifezeit,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE )
						).
					addGroup( eingabePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false ).
						addComponent( labelGramm, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( labelTage,GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ))));
	}

	public void panelButtonAnordnen(){
	
		panelButton.setLayout(new FlowLayout());
		panelButton.add(buttonOk);
		panelButton.add(buttonAbbrechen);
		
	}
	
	private void einfügenEnde() {
		
		Object[] options = {"Fertig!","Neue Pflanze!"};
		int selected = JOptionPane.showOptionDialog(null,"Pflanze hinzugefügt!", "Hinzufügen Erfolgreich", JOptionPane.YES_NO_OPTION,
					   JOptionPane.QUESTION_MESSAGE, null , options ,options[1]);
		
		switch(selected){
		case 0:
			dispose();
			break;
		case 1:
			loescheTextFelder();
			break;
		}
	}

	private void loescheTextFelder() {
		
		textfeldErtrag.setText(null);
		textfeldFarbe.setText(null);
		textfeldHerkunft.setText(null);
		textfeldReifezeit.setText(null);
		textfeldSorte.setText(null);	
		artListe.setSelectedIndex(0);
		schaerfeListe.setSelectedIndex(0);
		
	}

	private boolean ueberpruefeEingabe() {
		
		boolean pruefe = false;
		try {
			pruefe = hohleEingabe();
		} catch (EingabeException e) {
			System.out.println("Eingabe Fehlt");
		} catch (NumberFormatException n){
			System.out.println("Bitte Zahlen eingeben!");
			JOptionPane.showMessageDialog(null,"Bitte für Ertrag und Reifezeit Zahlen eingeben.","Fehler",JOptionPane.ERROR_MESSAGE);
		}
		return pruefe;
		
	}
	
	private boolean hohleEingabe() throws EingabeException,NumberFormatException {
		
		artString = (String) artListe.getSelectedItem();
		farbeString = textfeldFarbe.getText();
		herkunftString = textfeldHerkunft.getText();
		sorteString = textfeldSorte.getText();
		schaerfegradInt = Integer.parseInt((String) schaerfeListe.getSelectedItem());
		reifezeitInt = Integer.parseInt(textfeldReifezeit.getText());
		ertragInt = Integer.parseInt(textfeldErtrag.getText());
		stringBuilder.append(ertragInt).append(" gramm"); // an ertrag wird 'gramm' angehängt
		ertragString = stringBuilder.toString();
		stringBuilder.setLength(0);
		
		if(isEingabeLeer()){
			
			throw new EingabeException("Eine oder mehrere Eingaben fehlen, bitte keine negativen Zahlen/Nullwerte eingeben!");
			
		
		}else{
			
			return true;

		}
	}

	private boolean isEingabeLeer() {
	
		if(farbeString.length() == 0 || herkunftString.length() == 0 || sorteString.length() == 0 ||  reifezeitInt <= 0 || ertragInt <= 0){
		
			return true;
		
		}else{
		
			return false;
		
		}
	}
	
	private void fuegePflanzeEin() {
		/*
		 * Hier: andere Variante!
		 * Anders wie bei PflanzeBearbeitenFenster werden die einzelnen
		 * Attribute der Pflanze alle auf einmal in einer Methode zugewiesen.
		 */
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
	    Query q = em.createQuery("SELECT s FROM Schaerfegrad s WHERE  s.schaerfegrad = :name");
	    		  q.setParameter("name",schaerfegradInt);
    	
    	Schaerfegrad schaerfegrad = (Schaerfegrad) q.getSingleResult();
    	
    		
    	q = em.createQuery("SELECT h FROM Herkunft h WHERE  h.land = :name");
         	q.setParameter("name",herkunftString);
        
        Herkunft herkunft = (Herkunft) q.getSingleResult();
        
	    q = em.createQuery("SELECT a FROM Art a WHERE  a.art = :name");
    		q.setParameter("name",artString);
    	
    	Art art = (Art) q.getSingleResult();
        
		q = em.createQuery("SELECT f FROM Farbe f WHERE  f.farbe = :name");
     	 	q.setParameter("name", farbeString);
        
     	Farbe farbe = (Farbe) q.getSingleResult();
    	
		Pflanze pflanze = new Pflanze();
		
		pflanze.setSchaerfegrad(schaerfegrad);
		schaerfegrad.getPflanze().add(pflanze);
		
		pflanze.setHerkunft(herkunft);
		herkunft.getPflanze().add(pflanze);
		
		pflanze.setArt(art);
		art.getPflanze().add(pflanze);
		
		pflanze.setFarbe(farbe);
		farbe.getPflanze().add(pflanze);
		
		pflanze.setErtrag(ertragString);
		pflanze.setReifezeit(reifezeitInt);
		pflanze.setSorte(sorteString);
		
		em.persist(schaerfegrad);
		em.persist(art);
		em.persist(herkunft);
		em.persist(farbe);
		em.persist(pflanze);
		em.getTransaction().commit();
		em.close();
		
		
	}
	
	private void pruefeSchaerfegrad() {
		
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		
	    Query q = em.createQuery("SELECT s FROM Schaerfegrad s WHERE  s.schaerfegrad = :name");
	        	q.setParameter("name",schaerfegradInt);

	   if(q.getResultList().isEmpty()){
		   System.out.println("Schaerfegrad noch nicht vorhanden!");
		   em.close();
		   fuegeSchaerfegradEin();
	   }else{
		   System.out.println("Schaerfegrad schon vorhanden");
		   em.close();
	   }
	}

	private void fuegeSchaerfegradEin() {
	
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Schaerfegrad schaerfegrad = new Schaerfegrad();
		
		schaerfegrad.setSchaerfegrad(schaerfegradInt);
		
		em.persist(schaerfegrad);
		em.getTransaction().commit();
		em.close();
		
	}

	private void pruefeHerkunft() {
		
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
	    Query q = em.createQuery("SELECT h FROM Herkunft h WHERE  h.land = :name");
	        	q.setParameter("name",herkunftString);
	
	   if(q.getResultList().isEmpty()){
		   System.out.println("Herkunft noch nicht vorhanden!");
		   em.close();
		   fuegeHerkunftein();
	   }else{
		   System.out.println("Herkunft schon vorhanden!");
		   em.close();
	   }
	}

	private void fuegeHerkunftein() {
		
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Herkunft herkunft = new Herkunft();
		
		herkunft.setLand(herkunftString);
		em.persist(herkunft);
		em.getTransaction().commit();
		em.close();    	
		
	}

	private void pruefeArt() {
	
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
	    Query q = em.createQuery("SELECT a FROM Art a WHERE  a.art = :name");
	        	q.setParameter("name",artString);

	        
	   if(q.getResultList().isEmpty()){
		   System.out.println("Art noch nicht vorhanden!");
		   em.close();
		   fuegeArtEin();
	   }else{
		   System.out.println("Art schon vorhanden!");
		   em.close();
	   }
	}

	private void fuegeArtEin() {
		
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Art art = new Art();
		
		art.setArt(artString);
		em.persist(art);
		em.getTransaction().commit();
		em.close();
		
	}

	private void pruefeFarbe() {
	
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT f FROM Farbe f WHERE  f.farbe = :name");
      	 q.setParameter("name", farbeString);

      	 
      	 if(q.getResultList().isEmpty()){
      		System.out.println("Farbe noch nicht vorhanden!");
      		em.close();
      		fuegeFarbeEin();
 
      	 }else{
      		System.out.println("Farbe schon vorhanden!");
      		em.close();
      	 }
	}

	private void fuegeFarbeEin() {
		
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Farbe farbe = new Farbe();
		farbe.setFarbe(farbeString);
		
		em.persist(farbe);
		em.getTransaction().commit();
		em.close();
	}

	public boolean pflanzeNichtVorhanden() {
		
		boolean isVorhanden = false;
		try {
			
			isVorhanden = ueberpruefePflanze();
			
		} catch (EingabeException e) {
			System.out.println("Pflanze schon vorhanden Exception!");
		}

		return isVorhanden;			  
	}
	
	public boolean ueberpruefePflanze() throws EingabeException{

		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT p FROM Pflanze p WHERE  p.sorte = :name");
   	 			  q.setParameter("name", sorteString);
   	 			  
   	 	if(q.getResultList().size() == 0){
   	   	 	em.close();   
   	   	    System.out.println("Pflanzen Sorte noch nicht vorhanden.");
   	   	    return true;
   	 		   
   	 	 }else{
   	   	    em.close();
   	   	    throw new EingabeException("Pflanzen Sorte schon vorhanden.");
   	 	 }
	}
}
